﻿namespace MvvmTools
{
    using System;
    using System.ComponentModel;
    using JetBrains.Annotations;

    /// <summary>
    /// Property observable abstraction.
    /// </summary>
    public interface IPropertyObservable : IObservable<PropertyChange>, IDisposable
    {
        /// <summary>
        /// Gets target object for subscription.
        /// </summary>
        /// <value>
        /// The target.
        /// </value>
        INotifyPropertyChanged Target { [NotNull] get; }

        /// <summary>
        /// Suspends observer.
        /// </summary>
        /// <returns>
        /// Disposable instance to restore observer notifications.
        /// </returns>
        /// <example>
        /// Using suspend functionality.
        /// <code>
        /// interface IModel : INotifyPropertyChanged
        /// {
        ///     bool SomeFlag { get; }
        /// }
        /// 
        /// class ViewModel : NotificationModel
        /// {
        ///     IPropertyObservable anchor;
        /// 
        ///     ViewModel(IModel model)
        ///     {
        ///         anchor = (IPropertyObservable)model.Observe().OnValueChanged(i => i.SomeFlag).Subscribe(i => ModelFlagChanged())
        ///         Anchors.Add(anchor);
        ///     }
        /// 
        ///     private void ModelFlagChanged()
        ///     {
        ///         // handle model SomeFlag property changes
        ///     }
        /// 
        ///     private void Freeze()
        ///     {
        ///         anchor.Suspend(); // do not receive notification about model SomeFlag property changes
        ///     }
        /// }
        /// </code>
        /// </example>
        [NotNull] IDisposable Suspend();
    }
}
